import api from '@/store/api';
import { ReturnGetters, ActionContext } from '@/types/store';

const sortObjectByKeys = (obj: { [index: string]: any }) => {
  const sortedKeys = Object.keys(obj).sort();
  const sortedObj = {} as any;
  sortedKeys.forEach((key) => {
    sortedObj[key] = obj[key];
  });

  return sortedObj;
};

const state = {
  hostStatus: {},
};
type State = typeof state;

const getters = {
  hostStatus: (state: State) => {
    return state.hostStatus;
  },
};
type Getters = ReturnGetters<typeof getters>;

const mutations = {
  setHostStatus: (state: State, hostStatus: any) => {
    state.hostStatus = hostStatus;
  },
};
type Multations = keyof typeof mutations;

const actionsNames = ['getHostStatus'] as const;
type ActionNames = typeof actionsNames[number];

const actions = {
  async getHostStatus({
    commit,
  }: ActionContext<ActionNames, Multations, State, Getters>) {
    const chassisUrl = await api
      .get('/redfish/v1/Chassis/')
      .then(({ data: { Members } }) => Members[0]['@odata.id']);
    return await api
      .get(`${chassisUrl}/HostStatus/`)
      .then(async ({ data: { Members } }) => {
        const hardwaresInfo = { CPU: {}, Memory: {} } as any;
        const promises1 = [] as any[];
        Members.forEach(
          (member: {
            '@odata.id': string;
            Members?: { '@odata.id': string }[];
          }) => {
            const hardwareName = member['@odata.id'].split('/')[
              member['@odata.id'].split('/').length - 1
            ];
            const url = member['@odata.id'];
            const promise1 = api
              .get(url)
              .then(async ({ data }) => {
                if (!Object.hasOwnProperty.call(data, 'Members')) {
                  const temp = {} as any;
                  temp[hardwareName] = data.Data;
                  hardwaresInfo[hardwareName] = temp;
                } else {
                  const temp = {} as any;
                  const promises2 = [] as any[];
                  data.Members!.forEach((item: { '@odata.id': string }) => {
                    const compName = item['@odata.id'].split('/')[
                      item['@odata.id'].split('/').length - 1
                    ];
                    const promise2 = api
                      .get(item['@odata.id'])
                      .then(({ data: { Data } }) => {
                        temp[compName] = Data;
                      });
                    promises2.push(promise2);
                  });
                  await Promise.all(promises2);
                  hardwaresInfo[hardwareName] = sortObjectByKeys(temp);
                }
              })
              .catch((err) => {
                throw err;
              });
            promises1.push(promise1);
          }
        );
        await api.all(promises1).catch((err) => {
          throw err;
        });
        commit('setHostStatus', sortObjectByKeys(hardwaresInfo));
      })
      .catch((error) => {
        throw error;
      });
  },
};

const PerformanceMonitorStore = {
  namespaced: true,
  state,
  getters,
  mutations,
  actions,
};

export default PerformanceMonitorStore;
